package edu.cuit.zhuyimeng.ticket.service.impl;

import com.baomidou.dynamic.datasource.annotation.Master;
import com.baomidou.dynamic.datasource.annotation.Slave;
import edu.cuit.zhuyimeng.flight.api.dto.FlightInfoDTO;
import edu.cuit.zhuyimeng.framework.common.exception.UpdateException;
import edu.cuit.zhuyimeng.framework.common.system.enums.SysConstants;
import edu.cuit.zhuyimeng.framework.common.util.TimeUtils;
import edu.cuit.zhuyimeng.framework.workflow.util.ProcessUtils;
import edu.cuit.zhuyimeng.ticket.service.IDispatchJobService;
import edu.cuit.zhuyimeng.ticket.service.IFlightService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;
import tech.powerjob.client.PowerJobClient;
import tech.powerjob.common.enums.ExecuteType;
import tech.powerjob.common.enums.ProcessorType;
import tech.powerjob.common.enums.TimeExpressionType;
import tech.powerjob.common.request.http.SaveJobInfoRequest;
import tech.powerjob.common.response.ResultDTO;

import java.util.Map;

/**
 * 定时调度任务服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class JobDispatchService implements IDispatchJobService {

    private final RuntimeService runtimeService;
    private final PowerJobClient jobClient;

    private final IFlightService flightService;

    @Override
    @Master
    public void setCloseBookingJob(Long flightId) {
        SaveJobInfoRequest saveJobInfoRequest = new SaveJobInfoRequest();
        FlightInfoDTO flightInfoDTO = flightService.queryFlightInfo(flightId);
        log.info("航班 {} 开始设定关闭订票时间",flightInfoDTO.getNumber());
        saveJobInfoRequest.setJobName("关闭航班 " + flightInfoDTO.getNumber() + " 订票接口");
        saveJobInfoRequest.setJobDescription("自动关闭接口，关闭后后用户将不能订票");

        saveJobInfoRequest.setTimeExpressionType(TimeExpressionType.CRON);
        saveJobInfoRequest.setTimeExpression(TimeUtils.getCron(flightInfoDTO.getEndBook()));

        saveJobInfoRequest.setExecuteType(ExecuteType.STANDALONE);
        saveJobInfoRequest.setProcessorType(ProcessorType.BUILT_IN);
        saveJobInfoRequest.setProcessorInfo("closeTicketProcessor");

        saveJobInfoRequest.setJobParams(String.valueOf(flightId));

        ResultDTO<Long> longResultDTO = jobClient.saveJob(saveJobInfoRequest);

        if (longResultDTO.isSuccess()) {
            log.info("航班 {} 设置调度任务（关闭订票）完毕",flightInfoDTO.getNumber());
        } else {
            log.error("航班 {} 设置调度任务（关闭订票）失败: {}",flightInfoDTO.getNumber(),longResultDTO.getMessage());
            throw new UpdateException(longResultDTO.getMessage());
        }

        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(String.valueOf(flightId)).includeProcessVariables().singleResult();
        Map<String, Object> processVariables = processInstance.getProcessVariables();
        processVariables.put(SysConstants.JOB_ID_KEY,longResultDTO.getData());
        ProcessUtils.setVariables(processInstance,processVariables);
    }

    @Override
    @Master
    public void inactivateCloseBookingJob(Long flightId) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(String.valueOf(flightId)).includeProcessVariables().singleResult();
        Long jobId = (Long) processInstance.getProcessVariables().get(SysConstants.JOB_ID_KEY);
        ResultDTO<Void> deleteResult = jobClient.deleteJob(jobId);
        if (deleteResult.isSuccess()) {
            log.info("ID为 {} 的航班已经提前关闭任务（关闭订票接口任务）",flightId);
        }
    }
}
